package datei;

import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.WindowAdapter;
import java.awt.event.WindowEvent;
import java.io.File;
import java.io.IOException;

import javax.swing.JFileChooser;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileFilter;

/**
 * Der DateiMenuAdapter verbindet ein Fenster (JFrame) mit einer Klasse, welche das
 * Interface IDateiAnbindung implementiert (�ffnen, speichern von Dateien).
 * Der Konstruktor f�gt dem Fenster ein Datei-Menu hinzu.
 * In den Event-Handler-Methoden der Menus wird die typische Logik
 * f�r das Datei-Handling implementiert.
 * 
 * 
 * @author Radlbauer
 *
 */
public class DateiMenuAdapter
{
	private String suffix = ".item";
	
	private IDateiAnbindung anbindung;
	private JFrame frame;	
	private File file;
	private JFileChooser fileChooser;
	
	/**
	 * Der Konstruktor stellt die Verbindung zwischen der eigentlichen
	 * Dateianbindung (IDateiAnbindung) und dem Fenster her.
	 * 
	 * @param fenster
	 * @param anbindung
	 */
	public DateiMenuAdapter(JFrame fenster, IDateiAnbindung anbindung)
	{
		this.anbindung = anbindung;
		this.frame = fenster;
		initFileChooser();
		addMenus();
	}
	
	/**
	 * initialisiert den FileChooser-Dialog
	 */
	private void initFileChooser()
	{
		fileChooser = new JFileChooser(".");  // working directory
		fileChooser.setFileSelectionMode(JFileChooser.FILES_ONLY);
		fileChooser.setFileFilter(new FileFilter() {
			@Override
			public String getDescription()
			{
				return "Item-Dateien";
			}
			
			@Override
			public boolean accept(File f)
			{
				if (f.isFile())
					return f.getName().endsWith(suffix);
				return true;
			}
		});
	}
	
	
	/**
	 * f�gt dem Fenster zus�tzliche Datei-Menus hinzu.
	 */
	private void addMenus()
	{
		JMenuBar mbar = frame.getJMenuBar();
		JMenu datei = new JMenu("Datei");
		JMenuItem neu = new JMenuItem("neu");
		JMenuItem oeffnen = new JMenuItem("öffnen");
		JMenuItem speichern = new JMenuItem("speichern");
		JMenuItem speichernUnter = new JMenuItem("speichern unter");
		JMenuItem beenden = new JMenuItem("beenden");
		mbar.add(datei, 0);
		datei.add(neu);
		datei.add(oeffnen);
		datei.add(speichern);
		datei.add(speichernUnter);
		datei.add(beenden);
		
		neu.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				neu();
			}
		});
		oeffnen.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				oeffnen();
			}
		});
		speichern.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				speichern();
			}
		});
		speichernUnter.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				speichernUnter();
			}
		});
		beenden.addActionListener(new ActionListener() {
			
			@Override
			public void actionPerformed(ActionEvent arg0)
			{
				beenden();
			}
		});
		
		// Window Listener
		frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
		frame.addWindowListener(new WindowAdapter() {

			@Override
			public void windowClosing(WindowEvent e)
			{
				beenden();
			}
			
		});
		
	}

	
	// ======================= Implementierung der Menus =================
	
	/**
	 * beendet das Programm
	 * Vorher m�ssen eventuell �nderungen gespeichert werden.
	 */
	protected void beenden()
	{
		if (aenderungenSpeichern())
			System.exit(0);
	}

	/**
	 * zuerst wird abgefragt, ob der aktuelle Zustand gespeichert werden muss,
	 * dann wird die Methode neu() der Dateianbindung aufgerufen.
	 * 
	 * @return true, wenn wirklich ein neues Dokument angelegt wurde
	 */
	protected boolean neu()
	{
		if (aenderungenSpeichern())  // sollen vorher �nderungen gespeichert werden?
		{
			try
			{
				anbindung.neu();
				file = null;
				return true;
			} catch (IOException e)
			{
				e.printStackTrace();
				JOptionPane.showMessageDialog(frame, e.getMessage());
			}
		}

		return false;
	}
	

	/**
	 * Der Benutzer wird aufgefordert eine Datei anzugeben. 
	 * Falls die Datei schon existiert, muss das �berschreiben best�tigt 
	 * oder abgebrochen werden.
	 * 
	 * @return true, wenn tats�chlich gespeichert wurde
	 */
	protected boolean speichernUnter()
	{
		boolean fileOK = false;
		while(!fileOK)
		{
			// Datei-Auswahl
			if (fileChooser.showSaveDialog(frame) == JFileChooser.APPROVE_OPTION)
			{
				File f = fileChooser.getSelectedFile();
				// falls nicht die richtige Endung vorhanden ist,
				// wird dies angeh�ngt.
				if (!f.getName().endsWith(suffix))
					f = new File(f.getAbsolutePath() + suffix);
				if (f.exists())
				{
					// falls die Datei existiert, muss der Benutzer gefragt werden,
					// ob sie �berschieben werden soll.
					switch(JOptionPane.showConfirmDialog(frame, "existierende Datei �berschreiben?"))
					{
					case JOptionPane.YES_OPTION:  // Datei �berschreiben
						fileOK = true;
						file = f;
						break;
						
					case JOptionPane.CANCEL_OPTION:  // abbrechen
						return false;
						
					case JOptionPane.NO_OPTION:  
						// in diesem Fall lassen wir den Benutzer eine andere
						// Datei ausw�hlen
						break;
						
					}
					
				}
				else
				{
					// falls die Datei noch nicht existiert ist alle ok
					file = f;
					fileOK = true;
				}
			}
		}
				
		return speichern();
	}

	/**
	 * speichert die aktuelle Datei.
	 * Falls noch keine Datei angelegt wurde, wird speichernUnter() aufgerufen.
	 * 
	 * @return true, falls tats�chlich gespeichert wurde.
	 */
	protected boolean speichern()
	{
		if (file != null)
		{
			try
			{
				anbindung.speichern(file);
				return true;
			} catch (IOException e)
			{
				e.printStackTrace();
				JOptionPane.showMessageDialog(frame, e.getMessage());
				return false;
			}
		}
		else
			return speichernUnter();
	}

	/**
	 * �ffnet eine Datei.
	 * Vorher wird der Benutzer gefragt, ob er aktuelle �nderungen speichern soll.
	 * 
	 * @return true, falls tats�chlich eine Datei tats�chli ge�ffnet wurde
	 */
	protected boolean oeffnen()
	{
		if (!aenderungenSpeichern())
			return false;
		
		if (fileChooser.showOpenDialog(frame) == JFileChooser.APPROVE_OPTION)
		{
			file = fileChooser.getSelectedFile();
			try
			{
				anbindung.oeffnen(file);
				return true;
			} catch (IOException e)
			{
				e.printStackTrace();
				JOptionPane.showMessageDialog(frame, e.getMessage());
			}
		}
		return false;
	}

	/**
	 * �berpr�ft, ob �nderungen gespeichert werden m�ssen und speichert diese
	 * gegebenenfalls.
	 * 
	 * @return true, falls �nderungen gespeichert wurden oder nichts zu speichern war.
	 */
	protected boolean aenderungenSpeichern()
	{
		if (anbindung.aenderungen())
		{
			switch(JOptionPane.showConfirmDialog(frame, "�nderungen vorher speichern?"))
			{
			case JOptionPane.YES_OPTION:
				return speichern();
				
			case JOptionPane.CANCEL_OPTION:
				return false;
				
			case JOptionPane.NO_OPTION:
				return true;
			}
			return false;
		}
		else
			return true;  // keine �nderungen zu speichern
	}

}
